/* Filename: fork1.c
 * Description:
 * Last modified: humble 20200322 17:05
./fork1
1302 begin
1302 i am parent, child pid:1303
1302 end
1303 i am child
1303 end
父子进程谁先谁后执行由调度器决定
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

static void usage(void);

int main(int argc, char **argv) {
    if(argc != 1){ fprintf(stderr, "argc !=1"); usage(); exit(1); }
    // begin只在父进程打印一次。如果./fork1 > /tmp/out，那么在out文件可看到两个begin
    // 是因为文件默认是全缓冲模式，父进程的缓冲区还没刷新，那么子进程也会继承这部分缓冲区
    // 所以在fork()之前刷新缓冲区是一个好习惯fflush(NULL);
    printf("%d begin\n", getpid());
    fflush(NULL); // 刷新所有的成功打开的流

    pid_t pid = fork(); // 创建子进程
    if(pid < 0){ perror("fork()"); exit(1); } // 失败则没有子进程产生
    else if(pid == 0){ // 子进程
        printf("%d i am child\n", getpid());
    }
    else{ // 父进程
        // sleep(1); // 睡眠1秒，等待子进程先运行
        printf("%d i am parent, child pid:%d\n", getpid(), pid);
    }
    printf("%d end\n", getpid());
    //getchar(); // 加getchat()可以让父子都不退出，此时可以ps axf可以看到树状的父子结构
    //while(1);
    return 0;
}

static void usage(void) {
#define USAGE "Usage:\n\
  Helloworld\n"
    printf(USAGE);
}
